package com.cqupt.scanning.system.file.helper;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cqupt.scanning.system.acl.entity.AclUser;
import com.cqupt.scanning.system.acl.service.AclUserService;
import com.cqupt.scanning.system.admin.entity.*;
import com.cqupt.scanning.system.admin.service.DepartmentService;
import com.cqupt.scanning.system.admin.service.DeviceFootService;
import com.cqupt.scanning.system.admin.service.DeviceThreeService;
import com.cqupt.scanning.system.admin.service.OrganizationService;
import com.cqupt.scanning.system.file.entity.bo.MesurementBO;
import com.cqupt.scanning.system.file.entity.bo.MesurementBearingBo;
import com.cqupt.scanning.system.file.helper.utils.TimeFormatUtil;
import com.cqupt.scanning.system.statistics.entity.CalculatedDataThree;
import com.cqupt.scanning.system.statistics.service.CalculatedDataThreeService;
import com.cqupt.scanning.system.statistics.service.StatisticsService;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.Map;

/**
 * 生成三维报告
 * @Data: 2021/7/8 13:39
 * @Author: 宋宝梁
 */
@Component
public class GenerateThreePDF {

    @Autowired
    private FilePathConfig filePathConfig;

    @Autowired
    private CalculatedDataThreeService calculatedDataThreeService;

    private PatientThree patientThree;

    private PatientThreeBearing patientThreeBearing;

    @Autowired
    private AclUserService aclUserService;
    @Autowired
    private DeviceThreeService deviceThreeService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private OrganizationService organizationService;


    // 图片资源路径
    private String picturesPath;

    // 模板报告的名字
    private String templatePDF;

    // 报告输出的路径的根目录
    private String outFile;

    // 生成报告的名字(格式：yyyyMMddd-name.pdf)
    private String pdfName;


    public String getPdfName() {
        return pdfName;
    }

    //非负重
    public String execute(PatientThree patientThree,MesurementBO mesurementBO, PatientThreeBearing patientThreeBearing, MesurementBearingBo mesurementBearingBo,String templatePDF, String outFile) {
        this.patientThree = patientThree;
        this.patientThreeBearing = patientThreeBearing;
        this.templatePDF = templatePDF;
        this.outFile = outFile;
        DataSet dataSet = new DataSet();
        Map<String, String> dataMap = dataSet.getDataMap(patientThree, mesurementBO, patientThreeBearing, mesurementBearingBo);

        return doSomeThing(dataMap);
    }

    /**
     * 打印
     * @param dataMap
     * @return
     */
    private String doSomeThing(Map<String, String> dataMap) {
        String savePath = this.outFile + File.separator + TimeFormatUtil.getStrTime(TimeFormatUtil.ONE);
        File pdfPath = new File(savePath);
        if (!pdfPath.exists()) pdfPath.mkdirs();
        this.pdfName = TimeFormatUtil.getStrTime(TimeFormatUtil.ONE) + "-三维扫描-" + this.patientThree.getName() + ".pdf"; // pdf名字
        FileOutputStream fos = null;
        InputStream is = null;
        PdfReader reader = null;
        ByteArrayOutputStream baos = null;
        Document doc = null;
        try {
            fos = new FileOutputStream(savePath + File.separator + pdfName); // 生成pdf
            is = this.getClass().getResourceAsStream("/static/" + this.templatePDF); // 获取模板输入流
            reader = new PdfReader(is);
            baos = new ByteArrayOutputStream();
            PdfStamper stamp = new PdfStamper(reader, baos);
            AcroFields form = stamp.getAcroFields();
            setField(stamp, form, dataMap);
            stamp.setFormFlattening(true);
            stamp.close();
            doc = new Document();
            PdfCopy pdfCopy = new PdfCopy(doc, fos);
            doc.open();
            for (int i = 1; i <= 1; i++) { // 打印2页
                PdfImportedPage impPage = pdfCopy.getImportedPage(new PdfReader(baos.toByteArray()), i);
                pdfCopy.addPage(impPage);
            }
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(doc != null) doc.close();
                if(baos != null) baos.close();
                if(reader != null) reader.close();
                if(is != null) is.close();
                if(fos != null) fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        savePath = savePath + File.separator + this.pdfName;
        return savePath;
    }

    /**
     * 填值
     * @param stamper
     * @param form
     * @param dataMap
     */
    private void setField(PdfStamper stamper, AcroFields form, Map<String, String> dataMap) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String name = authentication.getName();
        AclUser username = aclUserService.getOne(new QueryWrapper<AclUser>().eq("username", name));
        DeviceThree three = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().eq("user_id", username.getId()));
        Department department = departmentService.getOne(new QueryWrapper<Department>().eq("id", three.getDepId()));
        Organization organization = organizationService.getOne(new QueryWrapper<Organization>().eq("org_num", department.getOrgNum()));
        String orgIconPath = organization.getOrgIconPath();
        for (String fieldName : dataMap.keySet()) {
            try {
                form.setField(fieldName, dataMap.get(fieldName)); // 填文本
            } catch (IOException | DocumentException e) {
                e.printStackTrace();
            }
            if(fieldName.equals(filePathConfig.getImageName18())) {
                imageToBytes(stamper, form, filePathConfig.getImageName18(), "18.jpg", 224F, 21F);
            }
            if(fieldName.equals(filePathConfig.getImageName19())) {
                imageToBytes(stamper, form, filePathConfig.getImageName19(), "19.jpg", 224F, 21F);
            }
            if(fieldName.equals(filePathConfig.getImageName20())) {
                imageToBytes(stamper, form, filePathConfig.getImageName20(), "17.jpg", 122F, 247F);
            }
            if(fieldName.equals(filePathConfig.getImageName21())) {
                imageToBytes(stamper, form, filePathConfig.getImageName21(), "16.jpg", 122F, 247F);
            }
            if(fieldName.equals(filePathConfig.getImageName22())) {
                imageToBytes(stamper, form, filePathConfig.getImageName22(), "1.jpg", 142F, 262F);
            }
            if(fieldName.equals(filePathConfig.getImageName23())) {
                imageToBytes(stamper, form, filePathConfig.getImageName23(), "0.jpg", 142F, 262F);
            }
            if(fieldName.equals(filePathConfig.getImageName24())) {
                imageToBytes(stamper, form, filePathConfig.getImageName24(), "20.jpg", 142F, 262F);
            }
            if(fieldName.equals(filePathConfig.getImageName25())) {
                imageToBytes(stamper, form, filePathConfig.getImageName25(), "21.jpg", 142F, 262F);
            }
            if((fieldName.equals(filePathConfig.getImageName68()))&& orgIconPath!=null){ // 报告logo-logoOne
                if(!orgIconPath.isEmpty()){
                    insertImage(stamper,form,filePathConfig.getImageName68(),orgIconPath);
                }
            }
        }
    }

    private void insertImage(PdfStamper stamper, AcroFields form, String imageName, byte[] imagePath, float newWidth, float newHeight) {

        int pageNo = form.getFieldPositions(imageName).get(0).page; // 获取图片所在当前页
        Rectangle signRect = form.getFieldPositions(imageName).get(0).position;
        float x = signRect.getLeft();
        float y = signRect.getBottom();
        try {
            // 读图片
            Image image = Image.getInstance(imagePath);
            image.setAlignment(Image.UNDERLYING);
            image.scaleAbsolute(newWidth, newHeight); // 设置图片大小
            // 获取操作的页面
            PdfContentByte under = stamper.getOverContent(pageNo);
            // 根据域的大小缩放图片
            image.scaleToFit(signRect.getWidth(), signRect.getHeight());
            // 添加图片
            image.setAbsolutePosition(x, y);
            under.addImage(image);
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }
    }

    private void insertImage(PdfStamper stamper, AcroFields form, String imageName, String imagePath) {
//        System.out.println("imageName:"+imageName+"imagePath:"+imagePath);
        int pageNo = form.getFieldPositions(imageName).get(0).page; // 获取图片所在当前页
        Rectangle signRect = form.getFieldPositions(imageName).get(0).position;
        float x = signRect.getLeft();
        float y = signRect.getBottom();
        try {
            // 读图片
            Image image = Image.getInstance(imagePath);
            // 获取操作的页面
            PdfContentByte under = stamper.getOverContent(pageNo);
            // 根据域的大小缩放图片
            image.scaleToFit(signRect.getWidth(), signRect.getHeight());
            // 定位图片坐标
            image.setAbsolutePosition(x, y);
            under.addImage(image);
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }
    }

    private void imageToBytes(PdfStamper stamper, AcroFields form, String imageName, String imgResource, float newWidth, float newHeight) {
        InputStream is = null;
        try {
            is = new FileInputStream(new File(picturesPath + File.separator + imgResource));
            byte[] imageBytes = StreamConvert.InputStreamToByte(is);
            insertImage(stamper, form, imageName, imageBytes, newWidth, newHeight);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is!=null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
